#include "pch.h"
#include "scene_node.h"
#include "scene.h"
#include "material.h"

c_scene_node::c_scene_node(c_scene *scene_mgr, const std::string& name)
    : m_name(name)
    , m_parent(NULL)
    , m_scene_mgr(scene_mgr)
    , m_local_transform(c_matrix4x4::Identity())
{
    BOOST_ASSERT(scene_mgr); 
}

c_scene_node::~c_scene_node()
{
}

void c_scene_node::add_child_node(const scene_node_ptr& child_node)
{
    BOOST_ASSERT(!(child_node->get_parent()));
    m_child_nodes.push_back(child_node);

    child_node->set_parent(this); 
}

void c_scene_node::remove_child_node(scene_node_ptr& child_node)
{
    m_child_nodes.erase(remove(m_child_nodes.begin(), m_child_nodes.end(), child_node), m_child_nodes.end());
}

void c_scene_node::set_parent(c_scene_node *parent)
{
    BOOST_ASSERT(parent);
    m_parent = parent;
}

c_scene_node* c_scene_node::get_parent() const 
{
    return m_parent;
}

void c_scene_node::set_local_transform(const c_matrix4x4& local_transform)
{
    m_local_transform = local_transform;
}

c_matrix4x4& c_scene_node::get_local_transfrom()
{
    return m_local_transform;
}

c_matrix4x4 c_scene_node::calc_world_transform() const
{
    if (!m_parent)
        return m_local_transform;

    return m_local_transform * m_parent->calc_world_transform(); 
}

bool c_scene_node::update(c_scene *scene, const float dt)
{
    foreach(scene_node_ptr& node_ptr, m_child_nodes) {
        node_ptr->update(scene, dt); 
    }
        
    return true; 
}

void c_scene_node::pre_render(c_scene *scene)
{
}

void c_scene_node::render(c_scene *scene)
{
    foreach(scene_node_ptr& node_ptr, m_child_nodes) {
        node_ptr->render(scene); 
    }
}

void c_scene_node::post_render(c_scene *scene)
{
}